const crypto = require('crypto');
const fs = require('fs');
const random = require('string-random')
const koaReq = require('request');
var Decimal = require('decimal.js');
const mysql = require('mysql');
const moment = require('moment');

module.exports = {
    /** 检测对象是否有字段为空 */
    validateObj(obj) {
        let res = false;
        let i = 0;
        let k = 0;
        for (const key in obj) {
            k++;
            if (obj[key] && obj[key] != '' && obj[key].toString().replace(/ /g, '').length > 0 && obj[key] != 'null' && obj[key] != 'NULL' && obj[key] != 'undefined') {
                i++;
            }
        }
        if (i === k) {
            res = true
        }
        return res;
    },
    /** 对象转义 */
    escapeObj(whereObj) {
        if (whereObj && JSON.stringify(whereObj).replace(/ /g, '').length > 0) {
            for (const key in whereObj) {
                if (whereObj[key])
                    whereObj[key] = mysql.escape(whereObj[key]);
            }
        }
        return whereObj;
    },
    /** 相加 */
    add(num1, num2) {
        return Number(new Decimal(num1).add(new Decimal(num2)).toNumber().toFixed(3));
    },
    /** 相减 */
    sub(num1, num2) {
        return Number(new Decimal(num1).sub(new Decimal(num2)).toNumber().toFixed(3));
    },
    /** 乘法 */
    mul(num1, num2) {
        return Number(new Decimal(num1).mul(new Decimal(num2)).toNumber().toFixed(3));
    },
    /** 除法 */
    div(num1, num2) {
        return Number(new Decimal(num1).div(new Decimal(num2)).toNumber().toFixed(3));
    },
    /** 时间戳产生函数 */
    createTimeStamp() {
        return parseInt(new Date().getTime() + '');
    },
    /** 产生随机数 */
    randomnum(n) {
        if (n > 21) return null
        return parseInt((Math.random() + 1) * Math.pow(10, n - 1))
    },
    /**md5 加密方法封装 */
    md5(buffer) {
        let obj = crypto.createHash('md5');
        obj.update(buffer);
        return obj.digest('hex');
    },
    unlink(path) {
        return new Promise((resolve, reject) => {
            fs.unlink(path, (err) => {
                if (err) {
                    reject(err)
                } else {
                    resolve();
                }
            })
        })
    },
    /** 
     * 接口返回数据方法封装
     */
    handleResulte(code, data, msg, page, token) {
        if (page) {
            return { code, data, msg, page }
        }
        if (token) {
            return { code, data, msg, token }
        }
        return { code, data, msg }
    },
    /** 签名加密算法 */
    signjsapi(ret, appSecret) {
        ret['nonce'] = random(32);
        ret = this.objKeySort(ret);
        //var string = this.raw(ret);
        var string = JSON.stringify(ret);
        string = string + 'secret=' + appSecret;
        console.log('加密前：', string);
        var sha1 = crypto.createHash('sha1');//创建哈希加密算法，后边可以是md5，sha1,sha256等
       // var sign = sha1.update(string, 'utf8').digest('hex'); //.toUpperCase();
        var sign = sha1.update(string).digest('hex');
        console.log('加密后：' + sign);
        ret['sign'] = sign;
        return ret;
    },

    /** 签名加密算法 */
    signjsapiv2(ret, appSecret) {
        //ret['appId'] = appId;
        //ret['nonce'] = nonce;
        ret = this.objKeySort(ret);
        var string = JSON.stringify(ret);
        string = string + 'secret=' + appSecret;
        console.log('加密前：', string);
        var sha1 = crypto.createHash('sha1');//创建哈希加密算法，后边可以是md5，sha1,sha256等
        var sign = sha1.update(string, 'utf8').digest('hex'); //.toUpperCase();
        console.log('加密后：' + sign);
        ret['sign'] = sign;
        return ret;
    },
    objKeySort(obj) {//排序的函数
        var newkey = Object.keys(obj).sort();
        //先用Object内置类的keys方法获取要排序对象的属性名，再利用Array原型上的sort方法对获取的属性名进行排序，newkey是一个数组
        var newObj = {};//创建一个新的对象，用于存放排好序的键值对
        for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
            newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
        }
        return newObj;//返回排好序的新对象
    },
    /** 参数排序 */
    raw(args) {
        var keys = Object.keys(args);
        keys = keys.sort()
        var newArgs = {};
        keys.forEach((key) => {
            var a = (args[key] + '').replace(/ /g, '');
            if (key != 'sign' && a.length > 0) {
                newArgs[key] = a;
            }
        });
        return JSON.stringify(newArgs);
    },
    /**
     * 请求第三方接口
     * url 接口地址，如：https://域名/apply_api/loan_amount_period/
     * data 请求body参数对象
     * method 请求方式：'get' 或 'post'
     */
    async webclient(url, data, method, ctx) {
        let res = await new Promise((resolve, reject) => {
            koaReq({
                url: url,
                method: method || 'post',
                headers: {//设置请求头
                    "content-type": "application/json",
                    //"token": token
                },
                body: data,
                json: true//设置返回的数据为json
            },
                (err, res, body) => {
                    if (!err && res.statusCode == 200) {
                        resolve(body);
                    }
                    resolve(err);
                });
        });
        // 记录请求日志
        let datenow = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
        console.log(url);
        console.log(JSON.stringify(data));
        console.log(JSON.stringify(res));
        await ctx.db.query(`INSERT INTO post_log (created_time,updated_time,url,method,postobj,res,state,message) 
        VALUES(?,?,?,?,?,?,?,?)`, [datenow, datenow, url, method || 'post', JSON.stringify(data), res ? JSON.stringify(res) : null, res ? res.code : null, res ? res.message : null]);
        return res;
    },

 
/**
 * @getClientIP
 * @desc 获取用户 ip 地址
 * @param {Object} req - 请求
 */
 getClientIP(req) {
    return req.headers['x-forwarded-for'] || // 判断是否有反向代理 IP
    req.headers['x-real-ip']||req.ip;
}

}